package org.ttitfly.workflow.engine.mode;

import org.apache.commons.beanutils.BeanUtils;
import org.ttitfly.workflow.SessionHolder;
import org.ttitfly.workflow.WFRequest;
import org.ttitfly.workflow.engine.Process;
import org.ttitfly.workflow.engine.VirtualRunUnit;
import org.ttitfly.workflow.engine.decider.ConditionsExpressionDecider;
import org.ttitfly.workflow.engine.decider.Decider;
import org.ttitfly.workflow.engine.run.ProcessInstance;
import org.ttitfly.workflow.engine.run.Task;
import org.ttitfly.workflow.exception.ProcessRunException;

/**
 * 合并节点
 * 
 * @author 潘海春
 * @version 2009-9-8
 */
public class Join extends VirtualRunUnit {

	/**
	 * 决策器
	 */
	private Decider decider;

	/**
	 * 下一个运行单元名称
	 */
	private String to;
	
	/**
	 * 构造函数
	 * 
	 * @param parent
	 *            流程定义
	 * @param name
	 *            名称
	 * @param conditions
	 *            条件表达式
	 * @param to
	 *            指向的运行单元
	 */
	public Join(Process parent, String name, String conditions, String to) {
		this(parent, name, new ConditionsExpressionDecider(conditions) {
			protected String parse(String conditions, WFRequest request) {
				int i = conditions.indexOf(VAR);
				while (i >= 0) {
					String var = conditions.substring(i + 2, conditions.indexOf(VAR_END));
					String varValue = "null";
					if (var.startsWith("_unit_") && var.endsWith("_status_")) {
						String unitName = var.replaceAll("^_unit_|_status_$", "");
						// 判断运行单元状态的
						ProcessInstance pi = SessionHolder.currentSession().currentProcessInstance();
						Task unitTask = null;
						for (Task task : pi.getTasks()) {
							if (task.getUnitName().equals(unitName)) {
								if (unitTask == null || unitTask.getActivationTime().before(task.getActivationTime())) {
									unitTask = task;
								}
							}
						}
						varValue = (unitTask == null) ? "null" : unitTask.getActionStatus();
						if (varValue == null || "".equals(varValue)) {
							varValue = "null";
						}
					} else {
						Object obj;
						try {
							obj = BeanUtils.getProperty(request.getAllVariables(), var);
						} catch (Exception e) {
							obj = null;
						}
						if (obj == null) {
							obj = request.getVariable(var);
						}
						if (obj != null) {
							varValue = obj.toString();
						}
					}
					conditions = conditions.replaceAll("\\" + VAR + "\\" + VAR_START + var + "\\" + VAR_END, varValue);
					i = conditions.indexOf(VAR);
				}
				return conditions;
			}
		}, to);
	}

	/**
	 * 构造函数
	 * 
	 * @param parent
	 *            流程定义
	 * @param name
	 *            名称
	 * @param decider
	 *            决策器
	 * @param to
	 *            指向的运行单元
	 */
	public Join(Process parent, String name, Decider decider, String to) {
		super(parent, name);
		if (decider == null) {
			throw new IllegalArgumentException("参数[decider]不能为空！");
		}
		this.decider = decider;
		if (to != null && !"".equals(to)) {
			this.to = to;
		}
	}

	@Override
	public void run() throws ProcessRunException {
		if (decider.decide()) {
			if (to == null) {
				parent.checkComplete();
			} else {
				parent.dispatch(to);
			}
		}
	}
	
}
